package com.cloudea.learn.component;

import com.cloudea.learn.Tensor;
import com.cloudea.learn.layer.Layer;

import java.lang.reflect.Field;
import java.util.*;

/**
 * 高层神经网络组件
 * @author cloudea
 * @date 2022/01/02
 */
public abstract class Component {
    private Map<String, Tensor> parameters = new HashMap<>();
    private String name;

    public Component(){
        this("layer");
    }

    public Component(String name){
        this.name = String.valueOf(name);
    }

    /**
     * 前向计算
     * @param inputs 输入
     * @return 输出
     */
    public Tensor forward(Tensor... inputs){
        //为参数创建对应的结点
        for (String parameterName : parameters.keySet()){
            Tensor tensor = parameters.get(parameterName);
            Layer.Node n = new Layer.Node();
            n.layer = null;
            n.output = tensor;
            tensor.setAttribute(Layer.NODE_ADDR_NAME,n );
        }
        return inputs[0];
    }

    /**
     * 创建参数
     * @param shape 参数的形状
     * @return 参数
     */
    protected Tensor createParameter(int... shape){
        //创建一个参数
        Tensor tensor = new Tensor(true, shape);  //使用BP算法来优化
        String name = UUID.randomUUID().toString();
        parameters.put(name, tensor);
        return tensor;
    }

    /**
     * 获取所有子计算结点
     * @return 计算结点
     */
    public List<Component> getChildren(){
        Class<?> cls = this.getClass();
        Field[] declaredFields = cls.getDeclaredFields();
        List<Component> components = new LinkedList<>();
        for (Field field : declaredFields){
            try {
                field.setAccessible(true);
                Object object = field.get(this);
                if(object instanceof Component){
                    Component component = (Component)object ;
                    components.add(component);
                }
            } catch (IllegalAccessException ignored) {}
        }
        return components;
    }
}
